/******************************************************************************
 * * mmi_modem_adaptor_ss.c - implementation of mmi-modem adaptor, ss sub-module
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "lv_watch.h"

#if USE_LV_WATCH_MODEM_ADAPTOR
#include "mmi_modem_adaptor_ss.h"
#include "mmi_modem_adaptor_nw.h"

/******************************************************************************
 *
 *         Functions
 *
 *******************************************************************************/

/**
 * initiate mmi-modem adaptor module
 * param (in) void:
 * return  void
 */
VOID MMI_ModemAdp_Ss_Init_Req()
{
}

/******************************************************************************
 *
 *         MMI -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * configure SS service call wait
 * param (in) SimId : MMI_MODEM_SIM_ID
 * param (in) CallForwardInfo : MMI_Modem_Call_Forward_Info_t
 * return void:
 */
VOID MMI_Modem_Call_Forward_Set_Req(MMI_MODEM_SIM_ID SimId, MMI_Modem_Call_Forward_Info_t * CallForwardInfo)
{
    MMI_Modemadp_Ss_Call_Forward_Set_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg = (MMI_Modemadp_Ss_Call_Forward_Set_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Ss_Call_Forward_Set_Req_t));

    pMsg->SimId           = SimId;
    pMsg->CallForwardInfo = CallForwardInfo;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_CALL_FORWARD_SET_REQ, (UI_Inter_Msg_t *)pMsg);
}

/**
 * get SS service call wait confirm
 * param (in) SimId  : MMI_MODEM_SIM_ID
 *       (in) CallForwardType : MMI_MODEM_CALL_FORWARD_TYPE
 * return MMI_Modem_Call_Forward_Info_t *
 */
MMI_Modem_Call_Forward_Info_t * MMI_Modem_Call_Forward_Get_Req(MMI_MODEM_SIM_ID SimId,MMI_MODEM_CALL_FORWARD_TYPE CallForwardType)
{
    MMI_Modem_Call_Forward_Info_t * CallForwardInfo = NULL;
    if(MMI_MODEM_CALL_FORWARD_NO_CONDITION == CallForwardType) {
        CallForwardInfo = &(g_ModemNwMng[SimId].NoConditionDivert);
    } else if(MMI_MODEM_CALL_FORWARD_BUSY == CallForwardType) {
        CallForwardInfo = &(g_ModemNwMng[SimId].BusyDivert);
    } else if(MMI_MODEM_CALL_FORWARD_NOT_REACH == CallForwardType) {
        CallForwardInfo = &(g_ModemNwMng[SimId].NotReachDivert);
    } else if(MMI_MODEM_CALL_FORWARD_NO_ANSWER == CallForwardType) {
        CallForwardInfo = &(g_ModemNwMng[SimId].NoAnswerDivert);
    }

    return CallForwardInfo;
}

/**
 * query SS service call wait
 * param (in) SimId           : MMI_MODEM_SIM_ID
 * param (in) CallForwardType : MMI_MODEM_CALL_FORWARD_TYPE(query type)
 * return void
 */
VOID MMI_Modem_Call_Forward_Query_Req(MMI_MODEM_SIM_ID SimId, MMI_MODEM_CALL_FORWARD_TYPE CallForwardType)
{
    MMI_Modemadp_Ss_Call_Forward_Query_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg = (MMI_Modemadp_Ss_Call_Forward_Query_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Ss_Call_Forward_Query_Req_t));

    pMsg->SimId           = SimId;
    pMsg->CallForwardType = CallForwardType;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_CALL_FORWARD_QUERY_REQ, (UI_Inter_Msg_t *)pMsg);
}

/**
 * configure SS service call wait
 * param (in) SimId : MMI_MODEM_SIM_ID
 * param (in) CallWaitOn : BOOL (true means call wait on)
 * return void:
 */
VOID MMI_Modem_Call_Wait_Set_Req(MMI_MODEM_SIM_ID SimId, BOOL CallWaitOn)
{
    MMI_Modemadp_Ss_Call_Wait_Set_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg = (MMI_Modemadp_Ss_Call_Wait_Set_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Ss_Call_Wait_Set_Req_t));

    pMsg->SimId      = SimId;
    pMsg->CallWaitOn = CallWaitOn;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_CALL_WAIT_SET_REQ, (UI_Inter_Msg_t *)pMsg);
}

/**
 * get SS service call wait
 * param (in) SimId : MMI_MODEM_SIM_ID
 * return uint8_t
 */
uint8_t MMI_Modem_Call_Wait_Get_Req(MMI_MODEM_SIM_ID SimId)
{
    return (uint8_t)(g_ModemNwMng[SimId].CcwaOnOffFlg);
}

/**
 * query SS service call wait
 * param (in) SimId : MMI_MODEM_SIM_ID
 * return void
 */
VOID MMI_Modem_Call_Wait_Query_Req(MMI_MODEM_SIM_ID SimId)
{
    MMI_Modemadp_Ss_Call_Wait_Query_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg = (MMI_Modemadp_Ss_Call_Wait_Query_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Ss_Call_Wait_Query_Req_t));

    pMsg->SimId = SimId;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_CALL_WAIT_QUERY_REQ, (UI_Inter_Msg_t *)pMsg);
}

/**
 * send ussd req
 * param (in) pSendUssdReq: MMI_Modem_Send_Ussd_Req_t
 * return  void
 */
VOID MMI_Modem_Send_Ussd_Req(MMI_Modem_Send_Ussd_Req_t * pSendUssdReq)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_SEND_USSD_REQ, (UI_Inter_Msg_t *)pSendUssdReq);
}

/**
 * ussd cancel
 * param (in) SimId: MMI_MODEM_SIM_ID
 * return  void
 */
VOID MMI_Modem_Ussd_Cancel_Req(MMI_MODEM_SIM_ID SimId)
{
    MMI_Modemadp_Ss_Ussd_Cancel_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg = (MMI_Modemadp_Ss_Ussd_Cancel_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Ss_Ussd_Cancel_Req_t));

    pMsg->SimId = SimId;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_USSD_CANCEL_REQ, (UI_Inter_Msg_t *)pMsg);
}

/******************************************************************************
 *
 *         RIL -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 *
 * param (in) SimId:  RIL_SIM_ID
 * param (in) s:  const char *
 * return  void
 */
VOID Ril_SS_Response_Cusd(RIL_SIM_ID SimId, const char * s)
{
    RIL_Modemadp_Ss_Rsp_Cusd_t * pMsg;
    UINT16                        CusdStringLen;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg          = (RIL_Modemadp_Ss_Rsp_Cusd_t *)Hal_Mem_Alloc(sizeof(RIL_Modemadp_Ss_Rsp_Cusd_t));
    CusdStringLen = strlen(s);

    pMsg->SimId      = SimId;
    pMsg->CusdString = Hal_Mem_Alloc(CusdStringLen + 1);
    strncpy(pMsg->CusdString, s, CusdStringLen + 1);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_SS_RSP_CUSD, (UI_Inter_Msg_t *)pMsg);
}

/**
 * Response query call forward info
 * param (in) sid:  RIL_SIM_ID
 * param (in) callforwardinfo:  RIL_CallForwardInfo
 * param (in) result:  RIL_Errno
 * return  void
 */
void Ril_SS_Response_Query_Call_Forward(RIL_SIM_ID sid, RIL_CallForwardInfo *callforwardinfo, RIL_Errno result)
{
    RIL_Modemadp_Ss_Rsp_Query_Call_Forward_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg          = (RIL_Modemadp_Ss_Rsp_Query_Call_Forward_t *)Hal_Mem_Alloc(sizeof(RIL_Modemadp_Ss_Rsp_Query_Call_Forward_t));

    pMsg->SimId      = sid;
    pMsg->callforwardinfo = callforwardinfo;
    pMsg->result = result;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_SS_RSP_QUERY_CALL_FORWARD, (UI_Inter_Msg_t *)pMsg);
}

/**
 * Response set call forward info
 * param (in) sid:  RIL_SIM_ID
 * param (in) result:  RIL_Errno
 * return  void
 */
void Ril_SS_Response_Set_Call_Forward(RIL_SIM_ID sid, RIL_Errno result)
{
    RIL_Modemadp_Ss_Rsp_Set_Call_Forward_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg          = (RIL_Modemadp_Ss_Rsp_Set_Call_Forward_t *)Hal_Mem_Alloc(sizeof(RIL_Modemadp_Ss_Rsp_Set_Call_Forward_t));

    pMsg->SimId      = sid;
    pMsg->result = result;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_SS_RSP_SET_CALL_FORWARD, (UI_Inter_Msg_t *)pMsg);
}

/**
 * Response query call waiting
 * param (in) sid:  RIL_SIM_ID
 * param (in) mode:  int
 * param (in) result:  RIL_Errno
 * return  void
 */
void Ril_SS_Response_Query_Call_Waiting(RIL_SIM_ID sid, int *mode, RIL_Errno result)
{
    RIL_Modemadp_Ss_Rsp_Query_Call_Waiting_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg          = (RIL_Modemadp_Ss_Rsp_Query_Call_Waiting_t *)Hal_Mem_Alloc(sizeof(RIL_Modemadp_Ss_Rsp_Query_Call_Waiting_t));

    pMsg->SimId      = sid;
    pMsg->mode = mode;
    pMsg->result = result;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_SS_RSP_QUERY_CALL_WAITING, (UI_Inter_Msg_t *)pMsg);
}

/**
 * Response set call waiting
 * param (in) sid:  RIL_SIM_ID
 * param (in) result:  RIL_Errno
 * return  void
 */
void Ril_SS_Response_Set_Call_Waiting(RIL_SIM_ID sid, RIL_Errno result)
{
    RIL_Modemadp_Ss_Rsp_Set_Call_Waiting_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg          = (RIL_Modemadp_Ss_Rsp_Set_Call_Waiting_t *)Hal_Mem_Alloc(sizeof(RIL_Modemadp_Ss_Rsp_Set_Call_Waiting_t));

    pMsg->SimId      = sid;
    pMsg->result = result;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_SS_RSP_SET_CALL_WAITING, (UI_Inter_Msg_t *)pMsg);
}

/******************************************************************************
 *
 *         Message Handler of MMI -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * Handler of MMI_MODEMADP_CALL_FORWARD_SET_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Call_Forward_Set_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Ss_Call_Forward_Set_Req_t * CallForwardSetReq;
    RIL_CallForwardInfo            *           forward;
    RIL_Errno                                 RilResult;

    printf("##interface## %s\n", __FUNCTION__);
    CallForwardSetReq = (MMI_Modemadp_Ss_Call_Forward_Set_Req_t *)Msg;

    forward = (RIL_CallForwardInfo *)Hal_Mem_Alloc(sizeof(RIL_CallForwardInfo));

    /* For RIL_REQUEST_SET_CALL_FORWARD:
     * status is:
     * 0 = disable
     * 1 = enable
     * 2 = interrogate
     * 3 = registeration
     * 4 = erasure
     */
    if(TRUE == CallForwardSetReq->CallForwardInfo->CallForwardOn) {
        forward->status = 1;    // enable
    } else {
        forward->status = 0;    // disable
    }

    /* <reason>: integer type, 27.007, 7.11
     * 0 unconditional
     * 1 mobile busy
     * 2 no reply
     * 3 not reachable
     * 4 all call forwarding (refer 3GPP TS 22.030 [19])
     * 5 all conditional call forwarding (refer 3GPP TS 22.030 [19])
     */
    if(MMI_MODEM_CALL_FORWARD_NO_CONDITION == CallForwardSetReq->CallForwardInfo->CallForwardType) {
        forward->reason = 0;
        if(TRUE == CallForwardSetReq->CallForwardInfo->CallForwardOn) {
            g_ModemNwMng[CallForwardSetReq->SimId].NoConditionDivert.CallForwardOn = 1;
            memcpy(g_ModemNwMng[CallForwardSetReq->SimId].NoConditionDivert.DestNum,CallForwardSetReq->CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
        } else {
            g_ModemNwMng[CallForwardSetReq->SimId].NoConditionDivert.CallForwardOn = 0;
            memset(g_ModemNwMng[CallForwardSetReq->SimId].NoConditionDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
        }
    } else if(MMI_MODEM_CALL_FORWARD_BUSY == CallForwardSetReq->CallForwardInfo->CallForwardType) {
        forward->reason = 1;
        if(TRUE == CallForwardSetReq->CallForwardInfo->CallForwardOn) {
            g_ModemNwMng[CallForwardSetReq->SimId].BusyDivert.CallForwardOn = 1;
            memcpy(g_ModemNwMng[CallForwardSetReq->SimId].BusyDivert.DestNum,CallForwardSetReq->CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
        } else {
            g_ModemNwMng[CallForwardSetReq->SimId].BusyDivert.CallForwardOn = 0;
            memset(g_ModemNwMng[CallForwardSetReq->SimId].BusyDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
        }
    } else if(MMI_MODEM_CALL_FORWARD_NOT_REACH == CallForwardSetReq->CallForwardInfo->CallForwardType) {
        forward->reason = 3;
        if(TRUE == CallForwardSetReq->CallForwardInfo->CallForwardOn) {
            g_ModemNwMng[CallForwardSetReq->SimId].NotReachDivert.CallForwardOn = 1;
            memcpy(g_ModemNwMng[CallForwardSetReq->SimId].NotReachDivert.DestNum,CallForwardSetReq->CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
        } else {
            g_ModemNwMng[CallForwardSetReq->SimId].NotReachDivert.CallForwardOn = 0;
            memset(g_ModemNwMng[CallForwardSetReq->SimId].NotReachDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
        }
    } else if(MMI_MODEM_CALL_FORWARD_NO_ANSWER == CallForwardSetReq->CallForwardInfo->CallForwardType) {
        forward->reason = 2;
        if(TRUE == CallForwardSetReq->CallForwardInfo->CallForwardOn) {
            g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.CallForwardOn = 1;
            memcpy(g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.DestNum,CallForwardSetReq->CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.NoAnswerDelay = CallForwardSetReq->CallForwardInfo->NoAnswerDelay;
        } else {
            g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.CallForwardOn = 0;
            g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.NoAnswerDelay = 20;
            memset(g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
        }
    } else if(MMI_MODEM_CALL_FORWARD_CANCEL_All == CallForwardSetReq->CallForwardInfo->CallForwardType) {
        forward->reason = 4;
        forward->status = 0;    // disable
        memset(&g_ModemNwMng[CallForwardSetReq->SimId].NoConditionDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
        memset(&g_ModemNwMng[CallForwardSetReq->SimId].BusyDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
        memset(&g_ModemNwMng[CallForwardSetReq->SimId].NotReachDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
        memset(&g_ModemNwMng[CallForwardSetReq->SimId].NoAnswerDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
    }

    // <class>
    forward->serviceClass = 1;  // voice

    // <number>
    forward->number = Hal_Mem_Alloc(NV_CONTACTS_MAX_NUMBER_LEN + 1);
    memset(forward->number, 0, NV_CONTACTS_MAX_NUMBER_LEN + 1);
    memcpy(forward->number, CallForwardSetReq->CallForwardInfo->DestNum, NV_CONTACTS_MAX_NUMBER_LEN);

    // <type>
    if((('0' == forward->number[0]) && ('0' == forward->number[1])) || ('+' == forward->number[0])) { // "00..." is an international number
        forward->toa = 145;
    } else {
        forward->toa = 129;
    }

    forward->timeSeconds = CallForwardSetReq->CallForwardInfo->NoAnswerDelay;

    RilResult = Ril_SS_Request_Set_Call_Forward(MMI_ModemAdp_Get_Ril_SimId(CallForwardSetReq->SimId), forward);
    printf("##interface## %s:RilResult is %d\n", __FUNCTION__,RilResult);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request call forward set req failed: %d\n", RilResult);
        MMI_Modem_Call_Forward_Set_Cnf(CallForwardSetReq->SimId, MMI_MODEM_ERROR);
    }
#if 0
    else {
        MMI_Modem_Call_Forward_Set_Cnf(CallForwardSetReq->SimId, CallForwardSetReq->CallForwardInfo,MMI_MODEM_SUCCESS);
    }
#endif

    Hal_Mem_Free(CallForwardSetReq->CallForwardInfo);
} /* MMI_ModemAdp_Ss_Call_Forward_Set_Req_Handler */

/**
 * Handler of MMI_MODEMADP_CALL_FORWARD_QUERY_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Call_Forward_Query_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Ss_Call_Forward_Query_Req_t * CallForwardQueryReq;

    RIL_CallForwardInfo             *            forward;
#if 0
    RIL_SS_REQUEST_QUERY_CALL_FORWARD_STATUS    result;
#endif
    RIL_Errno                                   RilResult;
    g_ModemNwMng[CallForwardQueryReq->SimId].Ccfc_Ccwa_ReadFlg = 1;

    printf("##interface## %s and Ccfc_Ccwa_ReadFlg is %d\n", __FUNCTION__,g_ModemNwMng[CallForwardQueryReq->SimId].Ccfc_Ccwa_ReadFlg);
    CallForwardQueryReq = (MMI_Modemadp_Ss_Call_Forward_Query_Req_t *)Msg;

    forward = (RIL_CallForwardInfo *)Hal_Mem_Alloc(sizeof(RIL_CallForwardInfo));
    memset(forward,0,sizeof(RIL_CallForwardInfo));

    /* For call forward query, only set <reason>
     * <reason>: integer type, 27.007, 7.11
     * 0 unconditional
     * 1 mobile busy
     * 2 no reply
     * 3 not reachable
     * 4 all call forwarding (refer 3GPP TS 22.030 [19])
     * 5 all conditional call forwarding (refer 3GPP TS 22.030 [19])
     */
    if(MMI_MODEM_CALL_FORWARD_NO_CONDITION == CallForwardQueryReq->CallForwardType) {
        forward->reason = 0;
    } else if(MMI_MODEM_CALL_FORWARD_BUSY == CallForwardQueryReq->CallForwardType) {
        forward->reason = 1;
    } else if(MMI_MODEM_CALL_FORWARD_NOT_REACH == CallForwardQueryReq->CallForwardType) {
        forward->reason = 3;
    } else if(MMI_MODEM_CALL_FORWARD_NO_ANSWER == CallForwardQueryReq->CallForwardType) {
        forward->reason = 2;
    }

    // <class>
    forward->serviceClass = 1;  // voice

    forward->status = 2;   //query status
    
    RilResult = Ril_SS_Request_Query_Call_Forward_Status(MMI_ModemAdp_Get_Ril_SimId(CallForwardQueryReq->SimId), forward, NULL);
    printf("##interface## %s:RilResult is %d\n", __FUNCTION__,RilResult);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request call forward set req failed: %d\n", RilResult);
        MMI_Modem_Call_Forward_Query_Cnf(CallForwardQueryReq->SimId, MMI_MODEM_ERROR, NULL);
    }
#if 0 
    else {
        QueryCnf                  = (MMI_Modem_Call_Forward_Info_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Call_Forward_Info_t));
        QueryCnf->CallForwardType = CallForwardQueryReq->CallForwardType;

        // we expect there is only one entry being included in result.forward
        if(1 == result.forward->status) {
            QueryCnf->CallForwardOn = TRUE;
        } else if(0 == result.forward->status) {
            QueryCnf->CallForwardOn = FALSE;
        }
        NumberLen = strlen(result.forward->number);
        if(NumberLen > NV_CONTACTS_MAX_NUMBER_LEN) {
            NumberLen = NV_CONTACTS_MAX_NUMBER_LEN;
        }
        memcpy(QueryCnf->DestNum, result.forward->number, NumberLen);
        QueryCnf->NoAnswerDelay = result.forward->timeSeconds;
        MMI_Modem_Call_Forward_Query_Cnf(CallForwardQueryReq->SimId, MMI_MODEM_SUCCESS, QueryCnf);
    }
    Hal_Mem_Free(CallForwardQueryReq);
    if(NULL != result.forward) {
        for(i = 0; i < result.count; i++) {
            if(NULL != result.forward[i].number) {
                Hal_Mem_Free(result.forward[i].number);
            }
        }
        Hal_Mem_Free(result.forward);
    }
#endif
} /* MMI_ModemAdp_Ss_Call_Forward_Query_Req_Handler */

/**
 * Handler of MMI_MODEMADP_CALL_WAIT_SET_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Call_Wait_Set_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Ss_Call_Wait_Set_Req_t * CallWaitSetReq;
    RIL_SS_REQUEST_SET_CALL_WAITING    *    wait;
    RIL_Errno                              RilResult;

    printf("##interface## %s\n", __FUNCTION__);
    CallWaitSetReq = (MMI_Modemadp_Ss_Call_Wait_Set_Req_t *)Msg;

    wait = (RIL_SS_REQUEST_SET_CALL_WAITING *)Hal_Mem_Alloc(sizeof(RIL_SS_REQUEST_SET_CALL_WAITING));
    if(TRUE == CallWaitSetReq->CallWaitOn) {
        wait->mode = 1; // 0 for "disabled" and 1 for "enabled"
        g_ModemNwMng[CallWaitSetReq->SimId].CcwaOnOffFlg = 1;
    } else {
        wait->mode = 0;
        g_ModemNwMng[CallWaitSetReq->SimId].CcwaOnOffFlg = 0;
    }
    wait->classx = 1;    // voice

    RilResult = Ril_SS_Request_Set_Call_Waiting(MMI_ModemAdp_Get_Ril_SimId(CallWaitSetReq->SimId), wait);
    printf("##interface## %s:RilResult is %d\n", __FUNCTION__,RilResult);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request call wait set req failed: %d\n", RilResult);
        MMI_Modem_Call_Wait_Set_Cnf(CallWaitSetReq->SimId, MMI_MODEM_ERROR);
    }
#if 0
    else {
        MMI_Modem_Call_Wait_Set_Cnf(CallWaitSetReq->SimId, MMI_MODEM_SUCCESS);
    }
#endif
}

/**
 * Handler of MMI_MODEMADP_CALL_WAIT_QUERY_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Call_Wait_Query_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Ss_Call_Wait_Query_Req_t * CallWaitQueryReq;
    RIL_SS_REQUEST_QUERY_CALL_WAITING        result;
    RIL_Errno                                RilResult;
    g_ModemNwMng[CallWaitQueryReq->SimId].Ccfc_Ccwa_ReadFlg = 1;

    printf("##interface## %s and Ccfc_Ccwa_ReadFlg is %d\n", __FUNCTION__,g_ModemNwMng[CallWaitQueryReq->SimId].Ccfc_Ccwa_ReadFlg);
    CallWaitQueryReq = (MMI_Modemadp_Ss_Call_Wait_Query_Req_t *)Msg;

    int * classx = Hal_Mem_Alloc(sizeof(int));

    *classx = 1;

    RilResult = Ril_SS_Request_Query_Call_Waiting(MMI_ModemAdp_Get_Ril_SimId(CallWaitQueryReq->SimId), *classx, &result); // class 1 means voice
    printf("##interface## %s:RilResult is %d\n", __FUNCTION__,RilResult);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request call wait query req failed: %d\n", RilResult);
        MMI_Modem_Call_Wait_Query_Cnf(CallWaitQueryReq->SimId, FALSE, MMI_MODEM_ERROR);
    }
#if 0
    else {
        if(1 == result.status) {
            MMI_Modem_Call_Wait_Query_Cnf(CallWaitQueryReq->SimId, TRUE, MMI_MODEM_SUCCESS);
        } else {
            MMI_Modem_Call_Wait_Query_Cnf(CallWaitQueryReq->SimId, FALSE, MMI_MODEM_SUCCESS);
        }
    }
#endif
}

/**
 * Handler of MMI_MODEMADP_SEND_USSD_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Send_Ussd_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modem_Send_Ussd_Req_t * SendUssdReq;
    RIL_Errno                 RilResult;
    MMI_Modem_Send_Ussd_Cnf_t * pSendUssdCnf;

    SendUssdReq = (MMI_Modem_Send_Ussd_Req_t *)Msg;

    RilResult = Ril_SS_Request_Send_Ussd(MMI_ModemAdp_Get_Ril_SimId(SendUssdReq->SimId), SendUssdReq->pSendUssdReq);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request send ussd req failed: %d\n", RilResult);
        pSendUssdCnf               = (MMI_Modem_Send_Ussd_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Ussd_Cnf_t));
        pSendUssdCnf->SimId        = SendUssdReq->SimId;
        pSendUssdCnf->Result       = MMI_MODEM_UNKNOWN_CMD;
        pSendUssdCnf->pSendUssdCnf = NULL;
        MMI_Modem_Send_Ussd_Cnf(pSendUssdCnf);
    }
}

/**
 * Handler of MMI_MODEMADP_USSD_CANCEL_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ss_Ussd_Cancel_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Ss_Ussd_Cancel_Req_t * UssdCancelReq;
    RIL_Errno                            RilResult;

    UssdCancelReq = (MMI_Modemadp_Ss_Ussd_Cancel_Req_t *)Msg;

    RilResult = Ril_SS_Request_Cancel_Ussd(MMI_ModemAdp_Get_Ril_SimId(UssdCancelReq->SimId));
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request ussd cancel req failed: %d\n", RilResult);
    }
}

/******************************************************************************
 *
 *         Message Handler of RIL -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Ss_Rsp_Cusd_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_Modemadp_Ss_Rsp_Cusd_t * SsRspCusd;
    MMI_Modem_Send_Ussd_Cnf_t   *  pSendUssdCnf;

    SsRspCusd = (RIL_Modemadp_Ss_Rsp_Cusd_t *)Msg;

    pSendUssdCnf               = (MMI_Modem_Send_Ussd_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Ussd_Cnf_t));
    pSendUssdCnf->SimId        = MMI_ModemAdp_Get_UI_SimId(SsRspCusd->SimId);
    pSendUssdCnf->Result       = MMI_MODEM_CMD_SUCCESS;
    pSendUssdCnf->pSendUssdCnf = SsRspCusd->CusdString;
    MMI_Modem_Send_Ussd_Cnf(pSendUssdCnf);
}

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Ss_Rsp_Query_Call_Forward_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_Modemadp_Ss_Rsp_Query_Call_Forward_t * SsCallForwardQueryCnf = (RIL_Modemadp_Ss_Rsp_Query_Call_Forward_t *)Msg;
    RIL_CallForwardInfo       *callforwardinfo = SsCallForwardQueryCnf->callforwardinfo;
    MMI_Modem_Call_Forward_Info_t        *       QueryCnf;
    UINT8                                       NumberLen;

    printf("##interface## %s:result is %d\n", __FUNCTION__,SsCallForwardQueryCnf->result);
    if(RIL_E_SUCCESS == SsCallForwardQueryCnf->result) {
        QueryCnf                  = (MMI_Modem_Call_Forward_Info_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Call_Forward_Info_t));
        memset(QueryCnf,0,sizeof(MMI_Modem_Call_Forward_Info_t));
        printf("##interface## %s:reason is %d\n", __FUNCTION__,callforwardinfo->reason);
        if(0 == callforwardinfo->reason) {
            QueryCnf->CallForwardType = MMI_MODEM_CALL_FORWARD_NO_CONDITION;
        } else if(1 == callforwardinfo->reason) {
            QueryCnf->CallForwardType = MMI_MODEM_CALL_FORWARD_BUSY;
        } else if(3 == callforwardinfo->reason) {
            QueryCnf->CallForwardType = MMI_MODEM_CALL_FORWARD_NOT_REACH;
        } else if(2 == callforwardinfo->reason) {
            QueryCnf->CallForwardType = MMI_MODEM_CALL_FORWARD_NO_ANSWER;
        }

        // we expect there is only one entry being included in result.forward
        printf("##interface## %s:status is %d\n", __FUNCTION__,callforwardinfo->status);
        if(1 == callforwardinfo->status) {
            QueryCnf->CallForwardOn = TRUE;
        } else if(0 == callforwardinfo->status) {
            QueryCnf->CallForwardOn = FALSE;
        }

        if(callforwardinfo->number) {
            printf("##interface## %s:number is %s,len is %d\n", __FUNCTION__,callforwardinfo->number,strlen(callforwardinfo->number));
            NumberLen = strlen(callforwardinfo->number);
            if(NumberLen > NV_CONTACTS_MAX_NUMBER_LEN) {
                NumberLen = NV_CONTACTS_MAX_NUMBER_LEN - 1;
            }
            memcpy(QueryCnf->DestNum, callforwardinfo->number, NumberLen);
            Hal_Mem_Free(callforwardinfo->number);
        } else {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "callforwardinfo->number is NULL\n");
        }
        printf("##interface## %s:timeSeconds is %d\n", __FUNCTION__,callforwardinfo->timeSeconds);
        QueryCnf->NoAnswerDelay = callforwardinfo->timeSeconds;
        MMI_Modem_Call_Forward_Query_Cnf(MMI_ModemAdp_Get_UI_SimId(SsCallForwardQueryCnf->SimId), MMI_MODEM_SUCCESS, QueryCnf);
    } else {
        MMI_Modem_Call_Forward_Query_Cnf(MMI_ModemAdp_Get_UI_SimId(SsCallForwardQueryCnf->SimId), MMI_MODEM_ERROR, NULL);
    }
    Hal_Mem_Free(SsCallForwardQueryCnf->callforwardinfo);
}

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Ss_Rsp_Set_Call_Forward_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_Modemadp_Ss_Rsp_Set_Call_Forward_t * SsRspSetCallForward = (RIL_Modemadp_Ss_Rsp_Set_Call_Forward_t *)Msg;

    printf("##interface## %s:result is %d\n", __FUNCTION__,SsRspSetCallForward->result);
    if(RIL_E_SUCCESS == SsRspSetCallForward->result) {
        MMI_Modem_Call_Forward_Set_Cnf(MMI_ModemAdp_Get_UI_SimId(SsRspSetCallForward->SimId),MMI_MODEM_SUCCESS);
    } else {
        MMI_Modem_Call_Forward_Set_Cnf(MMI_ModemAdp_Get_UI_SimId(SsRspSetCallForward->SimId),MMI_MODEM_ERROR);
    }
}

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Ss_Rsp_Query_Call_Waiting_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_Modemadp_Ss_Rsp_Query_Call_Waiting_t * SsRspQueryCallWaiting = (RIL_Modemadp_Ss_Rsp_Query_Call_Waiting_t *)Msg;
    uint8_t CallWaitOn = (uint8_t)(*(SsRspQueryCallWaiting->mode));

    printf("##interface## %s:result is %d,CallWaitOn is %d\n", __FUNCTION__,SsRspQueryCallWaiting->result,CallWaitOn);

    if(RIL_E_SUCCESS == SsRspQueryCallWaiting->result) {
        MMI_Modem_Call_Wait_Query_Cnf(MMI_ModemAdp_Get_UI_SimId(SsRspQueryCallWaiting->SimId), CallWaitOn,MMI_MODEM_SUCCESS);
    } else {
        MMI_Modem_Call_Wait_Query_Cnf(MMI_ModemAdp_Get_UI_SimId(SsRspQueryCallWaiting->SimId), CallWaitOn,MMI_MODEM_ERROR);
    }
    Hal_Mem_Free(SsRspQueryCallWaiting->mode);
}

/**
 * Indicates incoming (received) USSD information. (+CUSD:)
 * +CUSD:<m>[,<str>,<dcs>]
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Ss_Rsp_Set_Call_Waiting_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_Modemadp_Ss_Rsp_Set_Call_Waiting_t * SsSetCallWaitingCnf = (RIL_Modemadp_Ss_Rsp_Set_Call_Waiting_t *)Msg;

    printf("##interface## %s:result is %d\n", __FUNCTION__,SsSetCallWaitingCnf->result);

    if(RIL_E_SUCCESS == SsSetCallWaitingCnf->result) {
        MMI_Modem_Call_Wait_Set_Cnf(MMI_ModemAdp_Get_UI_SimId(SsSetCallWaitingCnf->SimId), MMI_MODEM_SUCCESS);
    } else {
        MMI_Modem_Call_Wait_Set_Cnf(MMI_ModemAdp_Get_UI_SimId(SsSetCallWaitingCnf->SimId), MMI_MODEM_ERROR);
    }
}

/**
 * module event handler
 * param (in) pMsg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_SS_Msg_handle(UI_INTER_MSG_ID MsgId, UI_Inter_Msg_t * pMsg)
{
    switch(MsgId) {
        case MMI_MODEMADP_CALL_FORWARD_SET_REQ:
            MMI_ModemAdp_Ss_Call_Forward_Set_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_CALL_FORWARD_QUERY_REQ:
            MMI_ModemAdp_Ss_Call_Forward_Query_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_CALL_WAIT_SET_REQ:
            MMI_ModemAdp_Ss_Call_Wait_Set_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_CALL_WAIT_QUERY_REQ:
            MMI_ModemAdp_Ss_Call_Wait_Query_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_SEND_USSD_REQ:
            MMI_ModemAdp_Ss_Send_Ussd_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_USSD_CANCEL_REQ:
            MMI_ModemAdp_Ss_Ussd_Cancel_Req_Handler(pMsg);
            break;

        case RIL_MODEMADP_SS_RSP_CUSD:
            MMI_ModemAdp_Ril_Ss_Rsp_Cusd_Handler(pMsg);
            break;

        case RIL_MODEMADP_SS_RSP_QUERY_CALL_FORWARD:
            MMI_ModemAdp_Ril_Ss_Rsp_Query_Call_Forward_Handler(pMsg);
            break;

        case RIL_MODEMADP_SS_RSP_SET_CALL_FORWARD:
            MMI_ModemAdp_Ril_Ss_Rsp_Set_Call_Forward_Handler(pMsg);
            break;

        case RIL_MODEMADP_SS_RSP_QUERY_CALL_WAITING:
            MMI_ModemAdp_Ril_Ss_Rsp_Query_Call_Waiting_Handler(pMsg);
            break;

        case RIL_MODEMADP_SS_RSP_SET_CALL_WAITING:
            MMI_ModemAdp_Ril_Ss_Rsp_Set_Call_Waiting_Handler(pMsg);
            break;

        default:
            break;
    }
}
#endif // USE_LV_WATCH_MODEM_ADAPTOR
